﻿using System.Threading.Channels;

namespace CommandLib
{
    /// <summary>
    /// NETCORE管道通信技术（管道工厂）
    /// </summary>
    /// <typeparam name="T">类型</typeparam>
    public sealed class ChannelFactory<T>
    {
        private readonly static Dictionary<string, Channel<T>> Container = new Dictionary<string, Channel<T>>();
        /// <summary>
        /// 管道实例构建
        /// </summary>
        /// <param name="channelName"></param>
        public static void Create(string channelName = "")
        {
            var _channelName = channelName.Trim();
            if (_channelName.IsEmpty())
            {
                _channelName = typeof(T).FullName;
            }
            if (!Container.ContainsKey(_channelName))
            {
                Container.Add(_channelName, Channel.CreateUnbounded<T>());
            }
        }

        /// <summary>
        /// 管道数据写入
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool Write(T value, string chnameName = "")
        {
            var result = false;
            try
            {
                var _channelName = chnameName.Trim();

                if (_channelName.IsEmpty())
                {
                    _channelName = typeof(T).FullName;
                }
                if (Container.ContainsKey(_channelName))
                {
                    result = Container[_channelName].Writer.TryWrite(value);
                }
            }
            catch (Exception)
            {

                throw;
            }
            return result;
        }


        /// <summary>
        ///  管道读取,会阻塞线程
        /// </summary>
        /// <param name="action">执行委托方法</param>
        /// <param name="chnameName">管道名称</param>
        public static async void ReadAsync(Action<T> action, string chnameName = "")
        {
            var _channelName = chnameName.Trim();

            if (_channelName.IsEmpty())
            {
                _channelName = typeof(T).FullName;
            }
            if (Container.ContainsKey(_channelName))
            {
                var channel = Container[_channelName];
                while (await channel.Reader.WaitToReadAsync())
                {
                    if (channel.Reader.TryRead(out T rdata))
                    {
                        //获取管道队列业务处理
                        action(rdata);
                    }
                }
            }


        }
        /// <summary>
        /// 获取管道队列数
        /// </summary>
        /// <param name="chnameName">管道名称</param>
        /// <returns></returns>
        public static int GetMqCount(string chnameName = "")
        {
            var _channelName = chnameName.Trim();

            if (_channelName.IsEmpty())
            {
                _channelName = typeof(T).FullName;
            }
            if (Container.ContainsKey(_channelName))
            {
                return Container[_channelName].Reader.Count;
            }
            else
            {
                return -1;
            }

        }

        /// <summary>
        /// 关闭管道
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="channelName">管道名称</param>
        public static bool Close(String channelName = "")
        {
            var result = false;
            var _channelName = channelName.Trim();

            if (_channelName.IsEmpty())
            {
                _channelName = typeof(T).FullName;
            }
            if (Container.ContainsKey(_channelName))
            {
                Container[_channelName].Writer.Complete();
                result = Container.Remove(_channelName);
            }
            return result;
        }
    }
}
